﻿
// MainDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "main.h"
#include "MainDlg.h"
#include "TextInfoDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define WM_PROCESS_UPDATE (WM_USER + 100)
#define WM_PROCESS_FINISH (WM_USER + 101)

// CMainDlg 对话框
CMainDlg::CMainDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MAIN_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMainDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_MFCEDITBROWSE1, m_editInput);
	DDX_Control(pDX, IDC_MFCEDITBROWSE2, m_editOutput);
	DDX_Control(pDX, IDC_LIST1, m_listSubDir);
	DDX_Control(pDX, IDC_EDIT1, m_editParam);
	DDX_Control(pDX, IDC_BUTTON3, m_btnStart);
}

static UINT WorkerThreadRun(LPVOID pParam)
{
	CString msg;
	CString inputDir;
	CString outputDir;
	CString cmdParam;
	CMainDlg *dlg = (CMainDlg *)pParam;
	CListCtrl *list = &dlg->m_listSubDir;
	dlg->GetDlgItemText(IDC_MFCEDITBROWSE1, inputDir);
	dlg->GetDlgItemText(IDC_MFCEDITBROWSE2, outputDir);
	dlg->GetDlgItemText(IDC_EDIT1, cmdParam);
	for (int i = 0; i < list->GetItemCount(); i++)
	{
		if (list->GetCheck(i))
		{
			TCHAR srcPath[1024];
			TCHAR dstPath[1024];
			HANDLE hChildStdoutR;
			HANDLE hChildStdoutW;
			HANDLE hChildStderrR;
			HANDLE hChildStderrW;
			PROCESS_INFORMATION pi;
			SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
			CString name = list->GetItemText(i, 1);
			PathCombine(srcPath, inputDir, name);
			PathCombine(dstPath, outputDir, name + _T(".iso"));
			dlg->SendMessage(WM_PROCESS_UPDATE, i, (LPARAM)"Scaning...");

			if (!CreatePipe(&hChildStdoutR, &hChildStdoutW, &sa, 0))
			{
				dlg->SendMessage(WM_PROCESS_FINISH, 0, (LPARAM)"创建管道失败!");
				return 0;
			}
			if (!CreatePipe(&hChildStderrR, &hChildStderrW, &sa, 0))
			{
				dlg->SendMessage(WM_PROCESS_FINISH, 0, (LPARAM)"创建管道失败!");
				CloseHandle(hChildStdoutR);
				CloseHandle(hChildStdoutW);
				return 0;
			}

			CString cmd;
			cmd.Format(_T("oscdimg.exe %s \"%s\" \"%s\""), cmdParam, srcPath, dstPath);

			STARTUPINFO si = { sizeof(STARTUPINFO) };
			si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
			si.hStdOutput = hChildStdoutW;
			si.hStdError = hChildStderrW;
			si.wShowWindow = SW_HIDE;
			if (!CreateProcess(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
			{
				dlg->SendMessage(WM_PROCESS_FINISH, 0, (LPARAM)"创建进程失败!");
				CloseHandle(hChildStdoutR);
				CloseHandle(hChildStdoutW);
				CloseHandle(hChildStderrR);
				CloseHandle(hChildStderrW);
				return 0;
			}

			CloseHandle(hChildStdoutW);
			CloseHandle(hChildStderrW);

			BYTE temp;
			char line[4096];
			UINT size = 0;
			memset(line, 0, sizeof(line));
			while (ReadFile(hChildStderrR, &temp, 1, NULL, NULL))
			{
				if (temp >= ' ')
				{
					line[size++] = temp;
					continue;
				}
				if (size > 0)
				{
					size = 0;
					dlg->SendMessage(WM_PROCESS_UPDATE, i, (LPARAM)line);
					memset(line, 0, sizeof(line));
				}
			}

			DWORD dwCode;
			GetExitCodeProcess(pi.hProcess, &dwCode);
			if (dwCode != 0)
			{
				memset(line, 0, sizeof(line));
				ReadFile(hChildStdoutR, line, sizeof(line), NULL, NULL);
				dlg->SendMessage(WM_PROCESS_FINISH, 0, (LPARAM)line);
				CloseHandle(pi.hProcess);
				CloseHandle(pi.hThread);
				return 0;
			}
			CloseHandle(pi.hProcess);
			CloseHandle(pi.hThread);
		}
	}
	dlg->SendMessage(WM_PROCESS_FINISH, 1, NULL);
	return 0;
}

BEGIN_MESSAGE_MAP(CMainDlg, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON1, &CMainDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CMainDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON4, &CMainDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON3, &CMainDlg::OnBnClickedButton3)
	ON_EN_CHANGE(IDC_MFCEDITBROWSE1, &CMainDlg::OnEnChangeMfceditbrowse1)
	ON_MESSAGE(WM_PROCESS_UPDATE, &CMainDlg::OnProcessUpdate)
	ON_MESSAGE(WM_PROCESS_FINISH, &CMainDlg::OnProcessFinish)
END_MESSAGE_MAP()


// CMainDlg 消息处理程序
BOOL CMainDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	m_editInput.EnableFolderBrowseButton();
	m_editOutput.EnableFolderBrowseButton();
	m_editParam.SetWindowText(_T("-h -o -m -j2 -lNONAME"));
	m_listSubDir.SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_listSubDir.InsertColumn(0, _T("选中"), LVCFMT_LEFT, 40);
	m_listSubDir.InsertColumn(1, _T("名称"), LVCFMT_LEFT, 450);
	m_listSubDir.InsertColumn(2, _T("状态"), LVCFMT_LEFT, 100);
	return TRUE;
}

//全选
void CMainDlg::OnBnClickedButton1()
{
	for (int i = 0; i < m_listSubDir.GetItemCount(); i++)
	{
		m_listSubDir.SetCheck(i);
	}
}

//反选
void CMainDlg::OnBnClickedButton2()
{
	for (int i = 0; i < m_listSubDir.GetItemCount(); i++)
	{
		if (m_listSubDir.GetCheck(i))
		{
			m_listSubDir.SetCheck(i, FALSE);
		}
		else
		{
			m_listSubDir.SetCheck(i, TRUE);
		}
	}
}

//帮助
void CMainDlg::OnBnClickedButton4()
{
	LPCTSTR help = _T("oscdimg常用命令参数:\r\n")
		" -o\t优化文件体积(扫描重复文件)\r\n"
		" -h\t包含隐藏文件\r\n"
		" -m\t忽略文件大小限制\r\n"
		" -lXX\t设置标卷名为XX\r\n"
		" -n\t允许长文件名(ISO9660文件系统)\r\n"
		" -d\t允许小写文件名(ISO9660文件系统)\r\n"
		" -j1\t兼容ISO9660文件系统和Joliet文件系统\r\n"
		" -j2\t仅使用Joliet系统\r\n";
	CTextInfoDlg dlg;
	dlg.SetTextInfo(_T("打包参数说明"), help, 340, 220);
	dlg.DoModal();
}

//开始打包
void CMainDlg::OnBnClickedButton3()
{
	CString strOutput;
	m_editOutput.GetWindowText(strOutput);
	if (!PathIsDirectory(strOutput))
	{
		MessageBox(_T("输出文件夹无效或不存在!"), _T("参数错误"), MB_ICONWARNING);
		return;
	}
	for (int i = 0; i < m_listSubDir.GetItemCount(); i++)
	{
		if (m_listSubDir.GetCheck(i))
		{
			m_btnStart.EnableWindow(FALSE);
			AfxBeginThread(WorkerThreadRun, this);
			return;
		}
	}
	MessageBox(_T("没有选中任何文件夹!"), _T("参数错误"), MB_ICONWARNING);
}

void CMainDlg::OnEnChangeMfceditbrowse1()
{
	CFileFind finder;
	CString strDir;
	m_editInput.GetWindowText(strDir);
	CString strPath = strDir + _T("\\*.*");
	BOOL bWorking = finder.FindFile(strPath);
	int nItem = 0;
	m_listSubDir.DeleteAllItems();
	while (bWorking)
	{
		bWorking = finder.FindNextFile();
		if (finder.IsDirectory() && !finder.IsDots())
		{
			CString strDirName = finder.GetFileName();
			m_listSubDir.InsertItem(nItem, _T(""));
			m_listSubDir.SetItemText(nItem, 1, strDirName);
			m_listSubDir.SetCheck(nItem);
			nItem++;
		}
	}
	finder.Close();
}

afx_msg LRESULT CMainDlg::OnProcessUpdate(WPARAM wParam, LPARAM lParam)
{
	CString msg((LPCSTR)lParam);
	m_listSubDir.SetItemText(wParam, 2, msg);
	return 0;
}

afx_msg LRESULT CMainDlg::OnProcessFinish(WPARAM wParam, LPARAM lParam)
{
	if (wParam == 0)
	{
		CString msg((LPCSTR)lParam);
		CTextInfoDlg dlg;
		dlg.SetTextInfo(_T("打包失败"), msg, 640, 320);
		dlg.DoModal();
		m_btnStart.EnableWindow(TRUE);
	}
	else
	{
		MessageBox(_T("所有文件夹打包完毕!"), _T("打包成功"), MB_ICONINFORMATION);
		m_btnStart.EnableWindow(TRUE);
	}
	return 0;
}
